$( init );

var inputCanvas, inputContext;
var outputCanvas, outputContext;
var inputPixels;

// The mousemove event handler.
var drawing = false;
var x, y;  

function init()
{
    $('#version>p').replaceWith( "<p>Update: 18</p>" );
    
    // Find the canvas elements.
    inputCanvas = $("#character-input")[0];
    outputCanvas = $("#character-output")[0];
    
    // Get the 2D canvas contexts.
    inputContext = inputCanvas.getContext("2d");
    inputContext.lineWidth = 5;
    outputContext = outputCanvas.getContext("2d");
    
    outputContext.font = "80pt Arial";
    outputContext.fillText("讐", 20, 150); 

    // Attach the mousemove event handler.
    inputCanvas.addEventListener('mousemove', ev_mousemove, false);
    inputCanvas.addEventListener('mousedown', ev_mousedown, false);
    inputCanvas.addEventListener('mouseup', ev_mouseup, false);
}

  
function ev_mousedown (ev)
{
  inputContext.beginPath();
  inputContext.moveTo(x, y);
  drawing = true;
}

function ev_mouseup (ev)
{
  inputContext.closePath();
  drawing = false;
  calculateDifference();
}

function ev_mousemove (ev)
{
  var position = $(this).offset();
  x = ev.layerX - position.left;
  y = ev.layerY - position.top;

  // The event handler works like a drawing pencil which tracks the mouse 
  // movements. We start drawing a path made up of lines.
  if (drawing)
  {
    inputContext.lineTo(x, y);
    inputContext.stroke();
  }
}

function calculateDifference()
{
    inputPixels = inputContext.getImageData(0, 0, inputCanvas.width, inputCanvas.height).data;
    $('#difference>p').replaceWith("<p></p>");

    var text = $('textarea#text-input').val();
    for(var counter = 0; counter < text.length; counter++)
    {
        $('#difference').append( "<p>" + text[counter] + "</p>" );
    }
    
    $('#difference>p').sortElements(function(a, b){
      return evaluateCharacter($(a).text()) > evaluateCharacter($(b).text()) ? 1 : -1;
    });
}

function evaluateCharacter(character)
{
    outputContext.clearRect(0, 0, outputCanvas.width, outputCanvas.height);
    outputContext.fillText(character, 20, 150);

    var outputPixels = outputContext.getImageData(0, 0, outputCanvas.width, outputCanvas.height).data;
    
    var inputCharacteristics = new Array().
      concat(getVerticalDensity(inputPixels, inputCanvas.width, inputCanvas.height)).
      concat(getHorizontalDensity(inputPixels, inputCanvas.width, inputCanvas.height));
    console.log("Input length: " + inputCharacteristics.length);
    
    var outputCharacteristics = new Array().
      concat(getVerticalDensity(outputPixels, outputCanvas.width, outputCanvas.height)).
      concat(getHorizontalDensity(outputPixels, outputCanvas.width, outputCanvas.height));
    console.log("Output length: " + outputCharacteristics.length);

    var magInput = 0;
    var magOutput = 0;
    var cosSum = 0;
    
    for(var index = 0; index < inputCharacteristics.length; index++)
    {
        magInput += inputCharacteristics[index] * inputCharacteristics[index];
        magOutput += outputCharacteristics[index] * outputCharacteristics[index];
        cosSum += inputCharacteristics[index] * outputCharacteristics[index];
    }
    
    magInput = Math.sqrt(magInput);
    magOutput = Math.sqrt(magOutput);
    
    var difference = cosSum / (magInput * magOutput);
    
    console.log("Got " + difference);
    return difference;
}

function getVerticalDensity(pixels, width, height)
{
    var originalData = new Array();
    var firstPixel = height;
    var lastPixel = 0;
    
    for(var row = 0; row < height; row++)
    {
      var columnWeight = 0;
      for(var column = 0; column < width; column++)
      {
          columnWeight += getLuminance(pixels, column, row, width, height);
      }
      
      originalData[row] = columnWeight;
      if(columnWeight > 0)
      {
        if(row < firstPixel) { firstPixel = row; }
        if(row > lastPixel) { lastPixel = row; }
      }
    }
    
    var finalData = new Array(10);
    initialize(finalData, 0);
    
    for(var counter = 0; counter < 10; counter++)
    {
      finalData[counter] += originalData[firstPixel + Math.floor( (counter / 10) * (lastPixel - firstPixel) )];
    }
    
    return finalData;
}

function getHorizontalDensity(pixels, width, height)
{
    var originalData = new Array();
    var firstPixel = width;
    var lastPixel = 0;
    
    for(var column = 0; column < width; column++)
    {
      var rowWeight = 0;
      for(var row = 0; row < height; row++)
      {
          rowWeight += getLuminance(pixels, column, row, width, height);
      }
      
      originalData[column] = rowWeight;
      if(rowWeight > 0)
      {
        if(column < firstPixel) { firstPixel = column; }
        if(column > lastPixel) { lastPixel = column; }
      }
    }
    
    var finalData = new Array(10);
    initialize(finalData, 0);
    
    for(var counter = 0; counter < 10; counter++)
    {
      finalData[counter] += originalData[firstPixel + Math.floor( (counter / 10) * (lastPixel - firstPixel) )];
    }
    
    return finalData;
}

function getLuminance(pixels, x, y, width, height)
{
    var index = (y * 4 * width) + (x * 4)
    var luminance = pixels[index + 3];
    return luminance;
}

function initialize(array, value)
{
    for(var index = 0; index < array.length; index++)
    {
      array[index] = value;
    }
}
